/* 
    动机：
        1. 和【函数组合成类】相似；
        2. 如果代码中会对源数据进行更新，使用类更好；
        3. 如果使用变换，派生数据会被存储在新生成的记录中，一旦源数据被修改，我就会遭遇数据不一致。

    做法：
        1. 创建一个变换函数，输入参数就是需要变换的记录，并直接返回该记录的值；
        2. 挑选一块逻辑，将其主体移入变换函数中，把结果作为字段添加到输出记录中。修改客户端代码，令其使用这个新字段；
        3. 测试；
        4. 针对其他相关的计算逻辑，重复上述步骤。
    
    -- javascript 中不推荐使用【函数组合成变换】
*/

const reading = { customer: "ivan", quantity: 10, month: 5, year: 2017 };

// client 1
const aReading = acquireReading();
const baseCharge = baseRate(aReading.month, aReading.year) * aReading.quantity;

// client 2
const aReading2 = acquireReading();
const baseCharge2 = baseRate(aReading.month, aReading.year) * aReading.quantity;
const taxableCharge = Math.max(0, base - taxThreshold(aReading.year));

// client 3
const aReading3 = acquireReading();
const basicChargeAmount = calculateBaseCharge(aReading);

function calculateBaseCharge() {
    return baseRate(aReading.month, aReading.year) * aReading.quantity;
}

/******************************************************************************* */

// 创建一个变换函数
function enrichReading(original){
    // _.cloneDeep() 返回一个深拷贝
    const result = _.cloneDeep(original);
    result.baseCharge = calculateBaseCharge(result);
    result.taxableCharge = taxableCharge(result);
    return result;

    function calculateBaseCharge() {
        return baseRate(aReading.month, aReading.year) * aReading.quantity;
    }
    function taxableCharge(aReading){
        return  Math.max(0, aReading.baseCharge - taxThreshold(aReading.year));   
    }
}

// client 4
const rawReading4 = acquireReading();
const aReading4 = enrichReading(rawReading4);
const basicChargeAmount4 = aReading4.baseCharge;
const taxableCharge4 = aReading4.taxableCharge;

